package com.yulan.bankback.controller.bank;

import com.yulan.bankback.entity.constant.RedisKeyConstant;
import com.yulan.bankback.entity.model.admin.AbnormalUser;
import com.yulan.bankback.entity.model.bank.BankUser;
import com.yulan.bankback.entity.dto.bank.LoginDto;
import com.yulan.bankback.entity.result.RetResponse;
import com.yulan.bankback.entity.result.RetResult;
import com.yulan.bankback.log.Logger;
import com.yulan.bankback.mapper.admin.AbnormalUserMapper;
import com.yulan.bankback.mapper.bank.BankUserMapper;
import com.yulan.bankback.service.bank.AuthService;
import com.yulan.bankback.service.bank.RedisService;
import com.yulan.bankback.service.bank.RiskService;
import com.yulan.bankback.util.IpUtil;
import lombok.extern.slf4j.Slf4j;
import net.ipip.ipdb.IPFormatException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
@RequestMapping("auth")
public class AuthController {

    @Autowired
    private AuthService authService;

    @Resource
    private BankUserMapper bankUserMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    @Qualifier("baseThreadPool")
    private ThreadPoolExecutor executor;

    @Resource
    private AbnormalUserMapper abnormalUserMapper;

    private static final long oneDay = 60 * 60 * 24 * 1000L;


    @Autowired
    private Logger logger;

    @PostMapping("login")
    public RetResult login(HttpServletRequest request, String account, String password){
        if(StringUtils.isBlank(account)) return RetResponse.makeErrRsp("账号不能为空");
        if(StringUtils.isBlank(password)) return RetResponse.makeErrRsp("密码不能为空");


        String token = request.getHeader("token");
        String type = request.getHeader("user_type");
        if(StringUtils.isNotBlank(token) && authService.verifyToken(token))
            return RetResponse.makeOKRspMsg("您已经登陆了，不需要重新登陆");


        String uid = authService.verifyPassword(account, password);
        if(StringUtils.isNotBlank(uid)){
            String newToken = authService.getToken(account);
            BankUser user = bankUserMapper.selectById(uid);
            if(type!=null && type.equals("admin") && user.getUserType().equals(0)){
                return RetResponse.makeErrRsp("只有管理员才能登陆");
            }

            user.setLastLoginTime(new Date());
            bankUserMapper.updateById(user);
            LoginDto loginDto = new LoginDto(account, uid, newToken, user.getUserName(), user.getPhone());

            redisService.set("token_" + newToken, uid, 60 * 60 * 24 * 1000L, TimeUnit.MILLISECONDS);
            redisService.lpush("user_id_list", uid);

            String ip = IpUtil.getIpAddr(request);
            log.info("用户请求的IP地址: {}", ip);
            executor.execute(() -> {
                authService.insertLoginEvent(uid, ip, "账号密码登陆");
                try {
                    String[] res = authService.checkRemoteLogin(uid, ip);
                    if(StringUtils.equals(res[0], "unsafe")){
                        redisService.hSet( RedisKeyConstant.REMOTE_LOGIN_MAP , uid, "1", oneDay, TimeUnit.MILLISECONDS);
                        abnormalUserMapper.insert(new AbnormalUser(uid,user.getUserName(),new Date(),"异地登陆", ip,""));
                        logger.logRemoteLogin(uid, ip, res[1]);
                    }
                } catch (IPFormatException | IOException e) {
                    e.printStackTrace();
                }
            });


            return RetResponse.makeOKRsp(loginDto);
        }

        return new RetResult().setCode(401).setMsg("密码错误或账号不存在");
    }

    @PostMapping("logout")
    public RetResult logout(@RequestParam(value = "token") String token){
        authService.removeToken(token);
        redisService.del("token_" + token);
        return RetResponse.makeOKRsp();
    }

    @PostMapping("register")
    public RetResult register(String username, String account, String password,
                              String payPassword, String phone, String messageCode, String bornDate){
        if(StringUtils.isBlank(username)) return RetResponse.makeErrRsp("昵称不能为空");
        if(StringUtils.isBlank(account)) return RetResponse.makeErrRsp("账号不能为空");
        if(StringUtils.isBlank(password)) return RetResponse.makeErrRsp("密码不能为空");
        if(StringUtils.isBlank(payPassword)) return RetResponse.makeErrRsp("支付密码不能为空");
        if(StringUtils.isBlank(phone)) return RetResponse.makeErrRsp("手机号不能为空");
        if(StringUtils.isBlank(messageCode)) return RetResponse.makeErrRsp("验证码不能为空");
        if(StringUtils.isBlank(bornDate)) return RetResponse.makeErrRsp("生日不能为空");
        String oldCode = redisService.get(phone + "_register_msg");
        if(!StringUtils.equals(oldCode, messageCode))
            return RetResponse.makeErrRsp("验证码错误");
        String res = authService.register(username, account, password, payPassword, phone, bornDate);
        return res.equals("success") ? RetResponse.makeOKRsp("注册成功") : RetResponse.makeErrRsp(res);
    }




}
